﻿using System;
using System.Collections.Generic;
using System.Linq;
using Dexter.Domain.Model;
using Dexter.Domain.Results;
using Dexter.Logger.Contracts;
using Dexter.Repository.NHibernate.Queries;
using NHibernate;
using ISessionFactory = Dexter.Repository.NHibernate.SessionFactory.ISessionFactory;

namespace Dexter.Repository.NHibernate.Repositories {
	/// <summary>
	/// The implementation of <see cref="ILegacyUrlRepository"/>.
	/// </summary>
	/// <example>The following is an example of initializing 
	///          an <c>LegacyUrlRepository</c> type:
	///   <code>
	///       // Create the type.
	///       LegacyUrlRepository ds = new LegacyUrlRepository;
	/// 
	///       if ( null == ds )
	///           return;
	/// 
	///       return ds.DoSomething( 5 );
	///   </code>
	/// </example>
	public class LegacyUrlRepository : RepositoryBase<LegacyUrl>, ILegacyUrlRepository {
		/// <summary>
		/// Initializes a new instance of the <see cref="LegacyUrlRepository"/> class.
		/// </summary>
		/// <param name="sessionFactory">The session factory.</param>
		/// <param name="logger">The logger.</param>
		public LegacyUrlRepository(ISessionFactory sessionFactory, ILogger logger) : base(sessionFactory, logger) {}

		#region ILegacyUrlRepository Members

		/// <summary>
		/// Return a list of <see cref="LegacyUrl"/> with all properties loaded.
		/// </summary>
		/// <param name="pageIndex">Index of the page (0 based).</param>
		/// <param name="pageSize">The number of items to retrieve.</param>
		/// <returns>
		/// An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.
		/// </returns>
		/// <exception cref="ArgumentOutOfRangeException"> If <paramref name="pageIndex"/> is lesser than 0.</exception>
		///   
		/// <exception cref="ArgumentOutOfRangeException"> If <paramref name="pageSize"/> is lesser than 1.</exception>
		public IPagedResult<LegacyUrl> GetListPaged(int pageIndex, int pageSize) {
			return GetListPaged(pageIndex, pageSize, true);
		}

		/// <summary>
		/// Return a list of <see cref="LegacyUrl"/> with all properties loaded.
		/// </summary>
		/// <param name="pageIndex">Index of the page (0 based).</param>
		/// <param name="pageSize">The number of items to retrieve.</param>
		/// <param name="enableTracking">if set to <c>true</c> the tracking system of the return object will be enable.</param>
		/// <returns>
		/// An concrete implementation of <see cref="IPagedResult{T}"/>. The result will never be null.
		/// </returns>
		/// <exception cref="ArgumentOutOfRangeException"> If <paramref name="pageIndex"/> is lesser than 0.</exception>
		///   
		/// <exception cref="ArgumentOutOfRangeException"> If <paramref name="pageSize"/> is lesser than 1.</exception>
		public IPagedResult<LegacyUrl> GetListPaged(int pageIndex, int pageSize, bool enableTracking) {
			
			if(pageIndex < 0)
				throw new ArgumentOutOfRangeException("pageIndex", "Invalid page index");

			if (pageSize < 1)
				throw new ArgumentOutOfRangeException("pageSize", "Invalid page size");

			IFutureValue<long> total = Session.GetNamedQuery(KnownQueries.LegacyUrlRepository.GetLegacyUrlCount)
				.FutureValue<long>();

			IEnumerable<LegacyUrl> result = Session.GetNamedQuery(KnownQueries.LegacyUrlRepository.GetLegacyUrl)
				.SetFirstResult(pageIndex * pageSize)
				.SetMaxResults(pageSize)
				.SetReadOnly(!enableTracking)
				.Future<LegacyUrl>();

			return new PagedResult<LegacyUrl>(pageIndex, pageSize, result.ToList(), total.Value);
		}

		/// <summary>
		/// Adds the specified item.
		/// </summary>
		/// <param name="item">The item.</param>
		public override void Add(LegacyUrl item)
		{
			this.Save(item);
		}

		/// <summary>
		/// Removes the specified item.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <returns></returns>
		public override bool Remove(LegacyUrl item)
		{
			this.Delete(item);
			return true;
		}

		/// <summary>
		/// Saves the specified <see cref="LegacyUrl"/> into the repository.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <exception cref="ArgumentNullException"> If <paramref name="item"/> is <c>null</c>.</exception>
		public void Save(LegacyUrl item) {
			if(item == null)
				throw new ArgumentNullException("item", "Invalid legacy url");

			item.ValidateForSave();
			Session.SaveOrUpdate(item);
		}

		public void Update(LegacyUrl item) {
			if (item == null)
				throw new ArgumentNullException("item", "Invalid legacy url");

			item.ValidateForUpdate();
			Session.SaveOrUpdate(item);
		}

		public void Delete(LegacyUrl item) {
			if (item == null)
				throw new ArgumentNullException("item", "Invalid legacy url");

			item.ValidateForDelete();

			Session.Delete(item);
		}

		#endregion
	}
}